package org.ytor.common.util.excel;

import lombok.Data;
import org.ytor.common.anno.Excel;
import org.ytor.common.classmeta.FieldMetadata;
import org.ytor.common.util.Dates;
import org.ytor.common.util.Strs;
import org.ytor.common.util.convert.Converts;
import org.ytor.common.util.invoke.Reflects;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;

/**
 * created by yangtong on 2025/5/29 21:54:49
 * <br/>
 * Excel注解解析器
 */
@Data
public class ExcelAnnoHandler {

    /**
     * 要处理的字段
     */
    private final Field field;

    /**
     * 该字段对应的Excel注解
     */
    private final Excel excel;

    /**
     * Excel注解的handler对象创建工厂
     */
    private ExcelFieldHandlerFactory handlerFactory;

    public ExcelAnnoHandler(FieldMetadata field, ExcelFieldHandlerFactory handlerFactory) {
        this.field = field.getField();
        this.excel = field.getAnnotation(Excel.class);
        this.handlerFactory = handlerFactory;
    }

    public Boolean hasExcel() {
        return excel != null;
    }

    @SuppressWarnings("unchecked")
    public void parse(Object targetObj, Object value) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        if (value == null) {
            return;
        }
        //通过setter方法给targetObj对象的字段赋值
        String setter = "set" + Strs.firstCapitalize(field.getName());

        Object finalValue;
        //如果是日期Date类型
        if (value instanceof Date dateValue && Strs.isNotEmpty(excel.format())) {
            finalValue = Dates.format(dateValue, excel.format());

        } else {
            //依次调用处理器
            for (Class<? extends IExcelFieldHandler> handlerClass : excel.handlers()) {
                //从工厂中获取ExcelFieldHandler
                IExcelFieldHandler<Object, Object, Object> handler =
                        handlerFactory.getHandler(handlerClass);
                //执行处理器，并返回处理后的结果
                value = handler.handler(targetObj, field, value);
            }
            finalValue = value;
        }
        //判断finalValue是否与字段类型一致，如果不一致则调用类型转换器尝试转换
        if (finalValue.getClass().equals(field.getType())) {
            Reflects.invokeMethod(targetObj, setter, finalValue);
        } else {
            Reflects.invokeMethod(targetObj, setter, Converts.convert(finalValue, field.getType()));
        }
    }

}
